import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

public class talkSeverHandler extends SimpleChannelInboundHandler<String> {
   public String chengyuanpoesee;
    /**
     * 定义一个channle 组，管理所有的channel
     * GlobalEventExecutor.INSTANCE) 是全局的事件执行器，是一个单例
     */
    private static DefaultChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 为了实现私聊功能，这里key存储用户的唯一标识,
     * 客户端的端口号
     * 当然 这个集合也需要自己去维护 用户的上下线 不能像 ChannelGroup那样自己去维护
     */
    private static Map<String, Channel> map = new HashMap<>();

    //创建日期
    SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");

    /**
     * 服务器读取客户端的数据
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

        //获取当前通道
        Channel channel = ctx.channel();

        /**
         * 私聊，这里简单判断 如果内容里边包含#那么就是私聊
         */
       /* if (msg.contains("#")){
            String id = msg.split("#")[0];
            String body = msg.split("#")[1];
            Channel userChannel = map.get(id);
            System.out.println("userChannel: "+userChannel);
            //求出远程地址的 key值9609  /127.0.0.1:9609
            String key = channel.remoteAddress().toString().split(":")[1];
            userChannel.writeAndFlush(sdf.format(new Date())+"\n client "+key+" say : "+body);
        }*/


        //判断当前消息是不是自己发送的,循环遍历channelGroup组中的channel
        channelGroup.forEach(ch->{
            //如果循环遍历的不是当前的channel,就转发消息给其他客户
            if (channel != ch){
                //#
                String MSQ=msg;
                String[] arr=MSQ.split(":");
                //如果是硬件发来的数据
                //System.out.println("channel!=ch");
                if(arr[0].contains("hardware")){
                    System.out.println("000");
                    String[] str=arr[1].split("=");
                    //如果发来的数据是Integer类型的
                    if(str[0].equals("Integer")){
                        String tmp=str[1];
                        Integer i= Integer.valueOf(tmp);
                    }
                    //如果发来的数据是String类型的
                    else if(str[0].equals("String")){

                        String s=str[1];

                        System.out.println("硬件发来的数据");
                        System.out.printf("#硬件->"+s+"\n");

                        //2.
                        String repose=s;
                        System.out.println("*服务器-前端->"+repose+"\n");
                        this.chengyuanpoesee=repose;
                        //ch.writeAndFlush("client"+channel.remoteAddress()+" send message "+chengyuanpoesee+"\n");
                        ch.writeAndFlush(chengyuanpoesee);
                    }
                }

                //如果是前端发来的数据
                if(arr[0].equals("front-end")){
                    String[] str=arr[1].split("=");
                    //如果发来的是String类型的数据
                    if(str[0].equals("String")){
                        String s=str[1];
                        System.out.println("前端发来的数据");
                        System.out.println("#前端->"+s);
                        if (s.contains("apple")){
                            String repose="apple";
                            System.out.println("*服务器-硬件->"+repose);
                            this.chengyuanpoesee=repose;
                        }else if(s.contains("fan")){
                            String repose="fan";
                            System.out.println("*服务器-硬件->"+repose);
                            this.chengyuanpoesee=repose;
                        }else if(s.contains("beep")){
                            String repose="beep";
                            System.out.println("*服务器-硬件->"+repose);
                            this.chengyuanpoesee=repose;
                        }else if(s.contains("led")){
                            String repose="led";
                            System.out.println("*服务器-硬件->"+repose);
                            this.chengyuanpoesee=repose;
                        }else{
                            String repose="苹果2";
                            System.out.println("服务器给硬件发送数据失败");
                            this.chengyuanpoesee=repose;
                        }
                        ch.writeAndFlush(chengyuanpoesee);
                      /*  if (s.equals("apple")){
                            String repose="苹果";
                            System.out.println(repose);
                            this.chengyuanpoesee=repose;
                            System.out.println("chengyuanpoesee是:"+chengyuanpoesee);
                        }else{
                            String repose="苹果";
                            System.out.println(repose);
                            this.chengyuanpoesee=repose;
                            System.out.println("chengyuanpoesee是:"+chengyuanpoesee);
                        }*/
                        //String repose=hashMap.get(s);
                        //chengyuanpoesee=repose;
                        //ch.writeAndFlush("client"+channel.remoteAddress()+" send message "+repose+"\n");
                        //暂定是否要删,先直接将要发送的数据给到msg
                        /*ByteBuf respose_are=ctx.alloc().buffer();
                        byte[] bufrepose=repose.getBytes(StandardCharsets.UTF_8);
                        respose_are.writeBytes(bufrepose);*/
                        //以上是暂定内容
                        //ctx.writeAndFlush(respose_are);
                        //ch.writeAndFlush("client"+channel.remoteAddress()+" send message "+repose+"\n");
                    }
                    //如果发来的是Integer类型的数据
                    else if(str[0].equals("Integer")){
                        String tmp=str[1];
                        Integer i = Integer.valueOf(tmp);
                        ByteBuf buf= Unpooled.buffer(i.BYTES);
                        ByteBuf respose_are=ctx.alloc().buffer();
                        buf.writeInt(i);
                        //byte[] bufrepose=i.getBytes(StandardCharsets.UTF_8);
                        respose_are.writeBytes(buf);
                        //ctx.writeAndFlush(respose_are);
                        //ch.writeAndFlush("client"+channel.remoteAddress()+" send message "+respose_are+"\n");

                    }
                }

            }
        });
    }

    /**
     * handlerAdded 表示连接建立，一旦连接，第一个被执行
     * 将当前channel 加入到  channelGroup
     * 建立连接以后第一个调用的方法
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        /**
         * 将该客户加入聊天的信息推送给其它在线的客户端
         * 该方法会将 channelGroup 中所有的channel 遍历，并发送 消息，
         * 我们不需要自己遍历
         */
        //
        //channelGroup.writeAndFlush("client： "+channel.remoteAddress()+" join chatting"+" time is "+sdf.format(new Date())+"\n");
       // channelGroup.writeAndFlush("crazy");
        channelGroup.add(channel);
        // /127.0.0.1:9394
        String key = channel.remoteAddress().toString().split(":")[1];
        map.put(key, channel);
    }

    /**
     * 表示channel 处于活动状态, 提示 xx上线
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress()+" on-line...");
    }


    /**
     * 表示channel 处于不活动状态, 提示 xx离线了
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress()+" off-line...");
        //下线移除
        String key = channel.remoteAddress().toString().split(":")[1];
        map.remove(key);
    }

    /**
     * 断开连接，将xx客户离开的消息推送给当前在线的其他客户，有人下线了通知到其他在线的人
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //
        //channelGroup.writeAndFlush("client "+channel.remoteAddress()+" leaving\n");
        System.out.println("channelGroup size"+channelGroup.size());
        System.out.println("map size: "+map.size());
    }


    /**
     * 捕获异常
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //出现异常关闭通道
        ctx.channel().close();
    }
}
